package cn.tedu.kcircle.security.support.auto;

import cn.tedu.kcircle.security.support.filter.JwtAuthorizationFilter;
import cn.tedu.kcircle.security.support.handler.CustomAccessDeniedHandler;
import cn.tedu.kcircle.security.support.handler.CustomAuthenticationEntryPoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class CustomWebSecurityAutoConfiguration {
    private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
    private CustomAccessDeniedHandler customAccessDeniedHandler;
    private JwtAuthorizationFilter jwtAuthorizationFilter;

    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    public CustomWebSecurityAutoConfiguration(CustomAuthenticationEntryPoint customAuthenticationEntryPoint, CustomAccessDeniedHandler customAccessDeniedHandler, JwtAuthorizationFilter jwtAuthorizationFilter){
        this.customAuthenticationEntryPoint=customAuthenticationEntryPoint;
        this.customAccessDeniedHandler=customAccessDeniedHandler;
        this.jwtAuthorizationFilter=jwtAuthorizationFilter;
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        /**
         * 调整session的创建策略 改为不使用session
         * SessionCreationPolicy.STATELESS不使用 SessionCreationPolicy.NEVER不创建
         */
//        http.sessionManagement(httpSecuritySessionManagementConfigurer -> httpSecuritySessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.ALWAYS));
        //将自定义过滤器添加至SecurityFilterChain
        http.addFilterBefore(jwtAuthorizationFilter, UsernamePasswordAuthenticationFilter.class);
        //允许跨域请求
        http.cors(httpSecurityCorsConfigurer -> {});
        /**
         * 白名单 --ant风格
         * 不在白名单中的请求必须通过Security框架的认证
         * 检查是否SecurityContext中是否存在有效的Authentication实现类判断是否认证
         */
        String[] urls = {
                "/doc.html",
                "/webjars/**",
                "/v3/api-docs/**",
                "/favicon.ico",
                "/user/login",
                "/user/register"
//                "/test/**"
        };
//        RegexRequestMatcher[] matchers = Arrays.stream(urls).map(RegexRequestMatcher::regexMatcher).toArray(RegexRequestMatcher[]::new);

        http.authorizeHttpRequests(
                authorize -> authorize
//                        .anyRequest().permitAll()
                        .requestMatchers(urls).permitAll()  //  默认使用ant风格url进行匹配
////                        .requestMatchers("/test/authorize").hasAuthority("/admin")
                        .anyRequest().authenticated() // 其它必须登录才能访问
        ).exceptionHandling(httpSecurityExceptionHandlingConfigurer -> {
            httpSecurityExceptionHandlingConfigurer.authenticationEntryPoint(customAuthenticationEntryPoint);
            httpSecurityExceptionHandlingConfigurer.accessDeniedHandler(customAccessDeniedHandler);
        });
        // Spring Security 6 中默认是关闭登录表单的，这里如果添加以下代码则是开启登录表单。
        // 开启登录表单
        /**
         * 根据是否调用formLogin表示是否启用登录表单
         * 当尝试访问某个"需要已经通过认证"的资源 但当前却未通过认证
         * --如果启用类登录页 则自动重定向到登录页
         * --如果未启用登录页 则响应403错误
         */
//         http.formLogin(Customizer.withDefaults());

        // 禁用csrf 防伪造跨域攻击
        http.csrf(AbstractHttpConfigurer::disable);
        // 验证token
//        http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    public static void main(String[] args) {
        String pattern=".*\\.css";
        String s="webjars/css/app.ac23e017.css";
        System.out.println(s.matches(pattern));
    }
}
